package main

import (
	"os"
	"os/user"
	path "path/filepath"
	"strconv"
	"strings"
	"time"

	"code.google.com/p/go-coreutils/opt"
)

func usage(s string) {
	os.Stderr.WriteString("usage: ")
	os.Stderr.WriteString(s)
	os.Stderr.WriteString("\n")
	os.Exit(1)
}

func main() {
	defer func() {
		if e := recover(); e != nil {
			switch err := e.(type) {
			case string:
				os.Stdout.WriteString(os.Args[0] + ": " + err + "\n")
				os.Exit(1)
			default:
				panic(err)
			}
		}
	}()

	var err error
	ti := os.Getenv("t")
	if len(ti) > 0 {
		opt.BaseInvoked = ti
	}
	switch opt.BaseInvoked {
	case "true":
		os.Exit(0)
	case "false":
		os.Exit(1)
	case "echo":
		opt.Parse("n", "", true)
		var outputString = strings.Join(opt.Args, " ")
		if !opt.Flags['n'] {
			outputString += "\n"
		}
		_, err := os.Stdout.WriteString(outputString)
		if err != nil {
			os.Exit(1)
		}
	case "yes":
		var outputString = "y"
		if len(os.Args) > 1 {
			outputString = strings.Join(os.Args[1:], " ")
		}
		outputString += "\n"
		var err error
		for err == nil {
			_, err = os.Stdout.WriteString(outputString)
		}
		os.Exit(1)
	case "sleep":
		opt.Parse("", "", false)
		if len(opt.Args) != 1 {
			usage("sleep <seconds>")
		}
		s := 0
		if s, err = strconv.Atoi(opt.Args[0]); err != nil {
			usage("sleep <seconds>")
		}
		time.Sleep(time.Duration(s) * time.Second)
	case "printenv":
		if len(os.Args) > 2 {
			usage("printenv [name]")
		} else if len(os.Args) == 2 {
			os.Stdout.WriteString(os.Getenv(os.Args[1]) + "\n")
		} else {
			for _, e := range os.Environ() {
				os.Stdout.WriteString(e + "\n")
			}
		}
	case "basename":
		if len(os.Args) != 2 {
			usage("basename <pathname>")
		}
		os.Stdout.WriteString(path.Base(os.Args[1]) + "\n")
	case "dirname":
		if len(os.Args) != 2 {
			usage("dirname <pathname>")
		}
		os.Stdout.WriteString(path.Dir(os.Args[1]) + "\n")
	case "pwd":
		p, err := os.Getwd()
		if err != nil {
			panic(err.Error())
		}
		os.Stdout.WriteString(p + "\n")
	case "whoami":
		u, err := user.Current()
		if err != nil {
			panic(err.Error())
		}
		os.Stdout.WriteString(u.Username + "\n")
	case "md5":
		hashCmd("md5")
	case "md5sum":
		hashCmd("md5")
	case "sha1":
		hashCmd("sha1")
	case "sha1sum":
		hashCmd("sha1")
	case "sha256":
		hashCmd("sha256")
	case "sha256sum":
		hashCmd("sha256")
	case "sha512":
		hashCmd("sha512")
	case "sha512sum":
		hashCmd("sha512")
	default:
		panic("unrecognized invocation: " + opt.BaseInvoked)
	}
}
